package com.zhonghui.modlules.cart.eshopService.Impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.eshop.apiCode.EshopException;
import com.eshop.service.Impl.BaseServiceImpl;
import com.zhonghui.common.eshopDozer.config.IGenerator;
import com.zhonghui.common.eshopEnum.CartTypeEnum;
import com.zhonghui.common.eshopEnum.OrderInfoEnum;
import com.zhonghui.common.eshopEnum.ProductTypeEnum;
import com.zhonghui.common.eshopEnum.ShopCommonEnum;
import com.zhonghui.common.eshopMapper.StoreBargainMapper;
import com.zhonghui.common.eshopMapper.StoreCombinationMapper;
import com.zhonghui.common.eshopMapper.StoreSeckillMapper;
import com.zhonghui.common.eshopService.StoreBargainService;
import com.zhonghui.common.eshopVo.StoreProductQueryVo;
import com.zhonghui.modlules.cart.eshopDomain.StoreBargain;
import com.zhonghui.modlules.cart.eshopDomain.StoreCart;
import com.zhonghui.modlules.cart.eshopMapper.StoreCartMapper;
import com.zhonghui.modlules.cart.eshopService.StoreCartService;
import com.zhonghui.modlules.cart.eshopVo.StoreCartQueryVo;
import com.zhonghui.modlules.product.eshopDomain.StoreProduct;
import com.zhonghui.modlules.product.eshopService.StoreProductAttrService;
import com.zhonghui.modlules.product.eshopService.StoreProductService;
import com.zhonghui.modlules.product.eshopVo.StoreProductAttrValue;
import com.zhonghui.modlules.user.eshopService.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional(
        propagation = Propagation.SUPPORTS,
        readOnly = true,
        rollbackFor = {Exception.class}
)
public class StoreCartServiceImpl  extends BaseServiceImpl<StoreCartMapper, StoreCart> implements StoreCartService {
    @Autowired
    private IGenerator generator;
    @Autowired
    private StoreCartMapper yxStoreCartMapper;
    @Autowired
    private StoreSeckillMapper storeSeckillMapper;
    @Autowired
    private StoreCombinationMapper storeCombinationMapper;
    @Autowired
    private StoreProductService productService;
    @Autowired
    private UserService userService;
    @Autowired
    private StoreBargainService storeBargainService;
    @Autowired
    private StoreBargainMapper storeBargainMapper;
    @Autowired
    private StoreProductAttrService productAttrService;

    public int getUserCartNum(Long uid) {
        return this.yxStoreCartMapper.cartSum(uid);
    }

    public long addCart(Long uid, Long productId, Integer cartNum, String productAttrUnique, Integer isNew, Long combinationId, Long seckillId, Long bargainId) {
        this.checkProductStock(uid, productId, cartNum, productAttrUnique, combinationId, seckillId, bargainId);
        LambdaQueryWrapper<StoreCart> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreCart::getUid, uid).eq( StoreCart::getIsPay, OrderInfoEnum.PAY_STATUS_0.getValue() )
                .eq(StoreCart::getProductId, productId).eq(StoreCart::getIsNew, isNew)
                .eq( StoreCart::getProductAttrUnique, productAttrUnique )
                .eq(StoreCart::getBargainId, bargainId)
                .eq(StoreCart::getCombinationId, combinationId)
                .eq(StoreCart::getSeckillId, seckillId)
                .orderByDesc( StoreCart::getId ).last("limit 1");

        StoreCart cart = (StoreCart)this.yxStoreCartMapper.selectOne(wrapper);
        StoreCart storeCart = StoreCart.builder().cartNum(cartNum).productAttrUnique(productAttrUnique).productId(productId).bargainId(bargainId).combinationId(combinationId).seckillId(seckillId).isNew(isNew).uid(uid).build();
        if (cart != null) {
            if (CartTypeEnum.NEW_0.getValue().equals(isNew)) {
                storeCart.setCartNum(cartNum + cart.getCartNum());
            }

            storeCart.setId(cart.getId());
            this.yxStoreCartMapper.updateById(storeCart);
        } else {
            this.yxStoreCartMapper.insert(storeCart);
        }

        return storeCart.getId();
    }
    public void changeUserCartNum(Long cartId, int cartNum, Long uid) {
        StoreCart cart = (StoreCart)((LambdaQueryChainWrapper)(lambdaQuery().eq(StoreCart::getUid, uid)).eq(StoreCart::getId, cartId)).one();
        if (cart == null) {
            throw new EshopException("购物车不存在");
        } else if (cartNum <= 0) {
            throw new EshopException("库存错误");
        } else {
            int stock = this.productService.getProductStock(cart.getProductId(), cart.getProductAttrUnique(), "");
            if (stock < cartNum) {
                throw new EshopException("该产品库存不足" + cartNum);
            } else if (cartNum != cart.getCartNum()) {
                StoreCart storeCart = new StoreCart();
                storeCart.setCartNum(cartNum);
                storeCart.setId(cartId);
                this.yxStoreCartMapper.updateById(storeCart);
            }
        }
    }

    public void checkProductStock(Long uid, Long productId, Integer cartNum, String productAttrUnique, Long combinationId, Long seckillId, Long bargainId) {
        Date now = new Date();
        StoreProduct product;
        int stock;
        if (combinationId != null && combinationId > 0L) {
            product = this.productService.lambdaQuery().eq(StoreProduct::getId, productId).eq(StoreProduct::getIsShow, ShopCommonEnum.SHOW_1.getValue()).one();
            if (product == null) {
                throw new EshopException("该产品已下架或删除");
            }

            stock = this.productService.getProductStock(productId, productAttrUnique, ProductTypeEnum.PINK.getValue());
            if (stock < cartNum) {
                throw new EshopException(product.getStoreName() + "库存不足" + cartNum);
            }
        } else if (seckillId != null && seckillId > 0L) {
            product = this.productService.lambdaQuery().eq(StoreProduct::getId, productId).eq(StoreProduct::getIsShow, ShopCommonEnum.SHOW_1.getValue()).one();
            if (product == null) {
                throw new EshopException("该产品已下架或删除");
            }

            stock = this.productService.getProductStock(productId, productAttrUnique, ProductTypeEnum.SECKILL.getValue());
            if (stock < cartNum) {
                throw new EshopException(product.getStoreName() + "库存不足" + cartNum);
            }
        } else if (bargainId != null && bargainId > 0L) {
            StoreBargain storeBargain = this.storeBargainService.lambdaQuery().eq(StoreBargain::getId, bargainId).eq(StoreBargain::getStatus, ShopCommonEnum.IS_STATUS_1.getValue()).le(StoreBargain::getStartTime, now).ge(StoreBargain::getStopTime, now).one();
            if (storeBargain == null) {
                throw new EshopException("该产品已下架或删除");
            }

            if (storeBargain.getStock() < cartNum) {
                throw new EshopException("该产品库存不足");
            }
        } else {
            product = this.productService.lambdaQuery().eq(StoreProduct::getId, productId).eq(StoreProduct::getIsShow, ShopCommonEnum.SHOW_1.getValue()).one();
            if (product == null) {
                throw new EshopException("该产品已下架或删除");
            }

            stock = this.productService.getProductStock(productId, productAttrUnique, "");
            if (stock < cartNum) {
                throw new EshopException(product.getStoreName() + "库存不足" + cartNum);
            }
        }
    }

    public Map<String, Object> getUserProductCartList(Long uid, String cartIds, Integer status) {
        LambdaQueryWrapper<StoreCart> wrapper = new LambdaQueryWrapper();
        wrapper.eq(StoreCart::getUid, uid).eq(StoreCart::getIsPay, OrderInfoEnum.PAY_STATUS_0.getValue()).orderByDesc(StoreCart::getId);
        if (status == null) {
            wrapper.eq(StoreCart::getIsNew, CartTypeEnum.NEW_0.getValue());
        }

        if (StrUtil.isNotEmpty(cartIds)) {
            wrapper.in(StoreCart::getId, Arrays.asList(cartIds.split(",")));
        }

        List<StoreCart> carts = this.yxStoreCartMapper.selectList(wrapper);
        List<StoreCartQueryVo> valid = new ArrayList();
        List<StoreCartQueryVo> invalid = new ArrayList();
        Iterator var8 = carts.iterator();

        while(true) {
            while(var8.hasNext()) {
                StoreCart storeCart = (StoreCart)var8.next();
                StoreProductQueryVo storeProduct = null;
                if (storeCart.getCombinationId() != null && storeCart.getCombinationId() > 0L) {
                    storeProduct = (StoreProductQueryVo) ObjectUtil.clone(this.storeCombinationMapper.combinatiionInfo(storeCart.getCombinationId()));
                } else if (storeCart.getSeckillId() != null && storeCart.getSeckillId() > 0L) {
                    storeProduct = (StoreProductQueryVo)ObjectUtil.clone(this.storeSeckillMapper.seckillInfo(storeCart.getSeckillId()));
                } else if (storeCart.getBargainId() != null && storeCart.getBargainId() > 0L) {
                    storeProduct = (StoreProductQueryVo)ObjectUtil.clone(this.storeBargainMapper.bargainInfo(storeCart.getBargainId()));
                } else {
                    storeProduct = (StoreProductQueryVo)ObjectUtil.clone(this.productService.getStoreProductById(storeCart.getProductId()));
                }

                StoreCartQueryVo storeCartQueryVo = (StoreCartQueryVo)this.generator.convert(storeCart, StoreCartQueryVo.class);
                if (ObjectUtil.isNull(storeProduct)) {
                    this.removeById(storeCart.getId());
                } else if (ShopCommonEnum.SHOW_0.getValue().equals(storeProduct.getIsShow()) || storeProduct.getStock() == 0 && StrUtil.isEmpty(storeCart.getProductAttrUnique())) {
                    storeCartQueryVo.setProductInfo(storeProduct);
                    invalid.add(storeCartQueryVo);
                } else if (StrUtil.isNotEmpty(storeCart.getProductAttrUnique())) {
                    StoreProductAttrValue productAttrValue = this.productAttrService.uniqueByAttrInfo(storeCart.getProductAttrUnique());
                    if (!ObjectUtil.isNull(productAttrValue) && productAttrValue.getStock() != 0) {
                        storeProduct.setAttrInfo(productAttrValue);
                        storeCartQueryVo.setProductInfo(storeProduct);
                        double vipPrice = this.userService.setLevelPrice(productAttrValue.getPrice().doubleValue(), uid);
                        if (storeCart.getBargainId() > 0L) {
                            vipPrice = storeProduct.getPrice().doubleValue();
                        }

                        if (storeCart.getCombinationId() > 0L) {
                            vipPrice = productAttrValue.getPinkPrice().doubleValue();
                        }

                        if (storeCart.getSeckillId() > 0L) {
                            vipPrice = productAttrValue.getSeckillPrice().doubleValue();
                        }

                        storeCartQueryVo.setTruePrice(vipPrice);
                        storeCartQueryVo.setVipTruePrice(productAttrValue.getPrice().doubleValue());
                        storeCartQueryVo.setCostPrice(productAttrValue.getCost().doubleValue());
                        storeCartQueryVo.setTrueStock(productAttrValue.getStock());
                        valid.add(storeCartQueryVo);
                    } else {
                        storeCartQueryVo.setProductInfo(storeProduct);
                        invalid.add(storeCartQueryVo);
                    }
                } else {
                    double vipPrice = this.userService.setLevelPrice(storeProduct.getPrice().doubleValue(), uid);
                    if (storeCart.getCombinationId() > 0L || storeCart.getSeckillId() > 0L || storeCart.getBargainId() > 0L) {
                        vipPrice = storeProduct.getPrice().doubleValue();
                    }

                    storeCartQueryVo.setTruePrice(vipPrice);
                    storeCartQueryVo.setVipTruePrice(0.0D);
                    storeCartQueryVo.setCostPrice(storeProduct.getCost().doubleValue());
                    storeCartQueryVo.setTrueStock(storeProduct.getStock());
                    storeCartQueryVo.setProductInfo(storeProduct);
                    valid.add(storeCartQueryVo);
                }
            }

            Map<String, Object> map = new LinkedHashMap();
            map.put("valid", valid);
            map.put("invalid", invalid);
            return map;
        }
    }


    public void removeUserCart(Long uid, List<String> ids) {
        List<Long> newids = (List)ids.stream().map(Long::new).collect( Collectors.toList());
        this.yxStoreCartMapper.delete((Wrapper) Wrappers.<StoreCart>lambdaQuery().eq(StoreCart::getUid, uid).in(StoreCart::getId, newids));
    }
}
